package com.rtx.express.service.impl;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.rtx.api.annotation.RtxExpressApi;
import com.rtx.common.DpopenSecurityUtil;
import com.rtx.edi.model.express.bo.ExpressBO;
import com.rtx.edi.model.express.dpopen.DpopenAddServices;
import com.rtx.edi.model.express.dpopen.DpopenOrderExtendFields;
import com.rtx.edi.model.express.dpopen.DpopenPackageInfo;
import com.rtx.edi.model.express.dpopen.DpopenReceiver;
import com.rtx.edi.model.express.dpopen.DpopenRequest;
import com.rtx.edi.model.express.dpopen.DpopenResponse;
import com.rtx.edi.model.express.dpopen.DpopenSender;
import com.rtx.edi.model.express.po.PlExpressApi;
import com.rtx.edi.model.express.po.PlExpressApiConfig;
import com.rtx.edi.model.express.po.PlExpressResult;
import com.rtx.express.service.IExpressService;

import cn.hutool.http.HttpRequest;

@RtxExpressApi(expressApiName = "德邦快递")
@Service("快递接口DBKD")
public class DpoponExpressAPI implements IExpressService{
	
	Logger log = LoggerFactory.getLogger(this.getClass());
	
	private static String create_order_url="http://gwapi.deppon.com/dop-interface-async/standard-order/createOrderNotify.action";//
	private static  String sign="NVBG";
	private static String companycode="EWBSHCFLGY";
	private static String customercode="668851885";
	private static String appkey="f2a5da909b39f1268009ef9f602dc0eb";

	@Override
	public void callCreaterOrderAPI(ExpressBO bo) {
		PlExpressApi task =  bo.getExpressTask();
		PlExpressApiConfig config = bo.getExpressConfig();
		try {
			
			//参数设置默认值
			mappingConfig(config);
			
			String timestamp = String.valueOf(System.currentTimeMillis());
			//转化德邦请求
			DpopenRequest dpopenRequest = convertDpopenRequest(bo);
			//德邦请求map
			Map<String,Object> map = new HashMap<>();
			//核算请求参数
			map.put("params", JSON.toJSONString(dpopenRequest));
			log.info("请求德邦参数"+JSON.toJSONString(dpopenRequest)+appkey+timestamp);
			//区域密文摘要
			map.put("digest", DpopenSecurityUtil.getDigest(JSON.toJSONString(dpopenRequest)+appkey+timestamp));
			//核算当前时间戳 ,当前时间毫秒数
			map.put("timestamp", timestamp);
			//核算第三方接入商的公司编码(双方约定,建议公司简拼或者代码,字母大写)
			map.put("companyCode", companycode);
			log.info("订单-"+task.getExternorderkey()+"-获取德邦快递单号请求数据：" + JSON.toJSONString(map));
			//发送请求
			String resultStr = HttpRequest
					.post(create_order_url)
					.form(map)
					.timeout(30000)
					.execute()
					.body();
			
			log.info("订单-"+task.getExternorderkey()+"-获取德邦快递单号返回结果：" + resultStr);
			DpopenResponse response = JSON.parseObject(resultStr, DpopenResponse.class);
			if("1000".equals(response.getResultCode())) {
				
				
				bo.setCallCreateOrderAPIResult("ok");
				bo.setCallCreateOrderAPIData(resultStr);
				
				PlExpressResult result = bo.getExpressResultFillSendAndReceiver();
				result.setResponseStr(bo.getCallCreateOrderAPIData());
				result.setExternorderkey(task.getExternorderkey());
				
				result.setWaybillNo(response.getMailNo());
				result.setDpoponlogisticID(response.getLogisticID());
				result.setDpoponarrivedOrgSimpleName(response.getArrivedOrgSimpleName());
				result.setDpoponparentMailNo(response.getParentMailNo());
				result.setDpoponuniquerRequestNumber(response.getUniquerRequestNumber());
				
				String default08 = Optional.ofNullable(bo.getDpopondefault08()).orElse("");
				if(default08.startsWith("A")||default08.startsWith("SA")) {
					result.setDpoponpaytype("到付");
				}else {
					result.setDpoponpaytype("月结");
				}
				
				
				bo.setExpressResult(result);
			}else {
				bo.setMsg(resultStr);
			}
			
		} catch (Exception e) {
			log.error("订单-"+task.getExternorderkey()+"-获取德邦快递单号失败：" + e.getMessage());
			bo.setCallCreateOrderAPIData("订单-"+task.getExternorderkey()+"-获取德邦快递单号失败：" + e.getMessage());
			bo.setMsg("订单-"+task.getExternorderkey()+"-获取德邦快递单号失败：" + e.getMessage());
		}
		
	}
	
	private void mappingConfig(PlExpressApiConfig config) {
		if(!StringUtils.hasLength(config.getUrl())) {
			config.setUrl(create_order_url);
		}
		if(!StringUtils.hasLength(config.getSign())) {
			config.setSign(sign);
		}
		if(!StringUtils.hasLength(config.getCompanycode())) {
			config.setCompanycode(companycode);
		}
		if(!StringUtils.hasLength(config.getCustomercode())) {
			config.setCustomercode(customercode);
		}
		if(!StringUtils.hasLength(appkey)) {
			config.setAppkey(appkey);
		}
	}
	
	public  DpopenRequest convertDpopenRequest(ExpressBO bo){
		PlExpressApi task =  bo.getExpressTask();
		PlExpressApiConfig config = bo.getExpressConfig();
		
		DpopenRequest req = new DpopenRequest();
		if(bo.getZdflag()) {
			req.setLogisticID(task.getLogisticid());
		}else {
			req.setLogisticID(sign+task.getExternorderkey());
		}
		req.setCustOrderNo(task.getExternorderkey());//	客户订单号/商户订单号	String	32	否	客户的订单号
		//req.setMailNo("");//	运单号	String	32	否	预埋单号时传运单号，不传时会返回运单号给客户
		req.setNeedTraceInfo(2);//	是否需要订阅轨迹	Integer		否	1：是（为是时要对接轨迹推送接口） 2：否 默认否
		req.setCompanyCode(companycode);//	第三方接入商的公司编码	String	32	是	渠道来源
		req.setOrderType("2");
		String default08 = Optional.ofNullable(bo.getDpopondefault08()).orElse("");
		if(default08.startsWith("A")||default08.startsWith("SA")) {
			req.setPayType("1");//支付方式	String	32	是	0:发货人付款（现付） 1:收货人付款（到付） 2：发货人付款（月结） （电子运单客户不支持寄付）
		}else {
			req.setPayType("2");//支付方式	String	32	是	0:发货人付款（现付） 1:收货人付款（到付） 2：发货人付款（月结） （电子运单客户不支持寄付）
		}
		
//		req.setTransportType(task.getDpopenTransportType());//	运输方式/产品类型	String	32	是	（具体传值请与月结合同签订约定的为准，否则可能影响计费） 快递运输方式 : 3.60特惠件：RCP; 3.60特重件：ZBRH ; 重包入户：NZBRH；重包特惠：ZBTH； 微小件特惠：WXJTH; 经济大件：JJDJ ; 标准快递 PACKAGE;特准快件 DEAP; 零担运输方式:精准空运 JZKY（仅散客模式支持该运输方式）; 精准汽运短途 JZQY_SHORT; 精准汽运长途 JZQY_LONG; 精准卡航 JZKH; 汽运偏线 AGENT_VEHICLE; 精准大票-经济件 DTD; 精准城运 JZCY; 精准大票-标准件 YTY; 精准包裹 PCP;
		req.setTransportType("PACKAGE");//	运输方式/产品类型	String	32	是	（具体传值请与月结合同签订约定的为准，否则可能影响计费） 快递运输方式 : 3.60特惠件：RCP; 3.60特重件：ZBRH ; 重包入户：NZBRH；重包特惠：ZBTH； 微小件特惠：WXJTH; 经济大件：JJDJ ; 标准快递 PACKAGE;特准快件 DEAP; 零担运输方式:精准空运 JZKY（仅散客模式支持该运输方式）; 精准汽运短途 JZQY_SHORT; 精准汽运长途 JZQY_LONG; 精准卡航 JZKH; 汽运偏线 AGENT_VEHICLE; 精准大票-经济件 DTD; 精准城运 JZCY; 精准大票-标准件 YTY; 精准包裹 PCP;
		req.setCustomerCode(customercode);//	客户编码/月结账号	String	32	是	下单模式为2时必填 德邦一线营业部给到客户的月结客户编码 ，是一串数字，由营业部给出。沙箱环境需要下子母件订单必须传值 219401 或者219402
		DpopenSender sender = new DpopenSender();
		sender.setCompanyName(task.getSendCompanyName());//	发货人公司	String	32	否	
//		sender.setBusinessNetworkNo(map.get("dpopen.post_code"));//	发货部门编码	String	32	否	德邦营业部门编码，若没有同步德邦营业部门数据，可以不填
		sender.setName(task.getSendName());//	发货人名称	String	32	是	
		sender.setMobile(task.getSendMobile());//	发货人手机	String	32	是	
		sender.setPhone(task.getSendPhone());//	发货人电话	String	32	否	
		sender.setProvince(task.getSendProvince());//	发货人省份	String	32	是	
		sender.setCity(task.getSendCity());//	发货人城市	String	32	是	
		sender.setCounty(task.getSendCounty());//	发货人区县	String	32	是	
		sender.setTown(task.getSendTown());//	发货人乡镇街道	String	32	否	
		sender.setAddress(task.getSendAddress());//	发货人详细地址	String	256	是
		req.setSender(sender);//	发货人信息	Sender		是	
		DpopenReceiver receiver = new DpopenReceiver();
		receiver.setToNetworkNo("");//	到达部门编码	String	32	否	德邦营业部门编码，若没有同步德邦营业部门数据，可以不填
		receiver.setName(task.getReceiverName());//	收货人名称	String	32	是	
		receiver.setPhone(task.getReceiverPhone());//	收货人电话	String	32	否	
		receiver.setMobile(task.getReceiverMobile());//	收货人手机	String	32	是	
		receiver.setProvince(task.getReceiverProvince());//	收货人省份	String	32	是	
		receiver.setCity(task.getReceiverCity());//	收货人城市	String	32	是	
		receiver.setCounty(task.getReceiverCounty());//	收货人区县	String	32	是	
		//receiver.setTown("");//	收货人镇街道	String	32	否	
		receiver.setAddress(task.getReceiverAddress());//	收货人详细地址	String	256	是	
		receiver.setCompanyName("");//	收货人公司	String	100	否
		req.setReceiver(receiver);//	收货人信息	Receiver		是	
		DpopenPackageInfo packageInfo = new DpopenPackageInfo();
		packageInfo.setCargoName("鞋服");//	货物名称	String	250	是	
		packageInfo.setTotalNumber(1);//	总件数（包裹数）	Integer	32	是	
		packageInfo.setTotalWeight(1D);//	总重量	double	Double (5,2)	是	单位kg
		packageInfo.setTotalVolume(0D);//	总体积	double	Double (5,2)	否	单位m3
		packageInfo.setPackageService("托木");//	包装	String	32	否	包装（直接用中文） ： 纸、纤、木箱、木架、托膜、托木（大客户模式下运输方式为零担时必填）
		packageInfo.setDeliveryType("4");//	送货方式	String	32	是	1、自提； 2、送货进仓； 3、送货（不含上楼）； 4、送货上楼； 5、大件上楼
		req.setPackageInfo(packageInfo);//	包裹信息	PackageInfo		是	
		req.setGmtCommit(new SimpleDateFormat("YYYY-MM-dd HH:mm:ss").format(new Date())); //	订单提交时间	String	32	是	2012-11-27 18:44:19 系统当前时间
		DpopenAddServices addServices = new DpopenAddServices();
		req.setAddServices(addServices); //	增值服务	AddServices	32	否	
		req.setSmsNotify("N");//	短信通知	String	32	否	Y：需要 N: 不需要
		req.setSendStartTime(null);//	上门接货开始时间	DateTime	32	否	方便上门接货的时间范围
		req.setSendEndTime(null);//	上门接货结束时间	DateTime	32	否	方便上门接货的时间范围
		req.setOriginalWaybillNumber("");//	原运单号	String	32	否	异地调货退货场景可能用到
		req.setRemark("");//备注	String	100	否	注意事项（备注）
		req.setIsOut("");//	是否外发	String	32	否	Y：需要 N: 不需要（大客户模式下运输方式为零担时必填）
		List<DpopenOrderExtendFields> orderExtendFields = null;
		req.setOrderExtendFields(orderExtendFields);
		return req;
	}

	@Override
	public void handleCreaterOrderAPIResponse(ExpressBO bo) {
	}

//	// 德邦随机数
//	public static String num() {
//		String num = "";
//		for (int n = 0; n < 10; n++) {
//			num += (int) (14 * (Math.random()));
//		}
//		return num;
//	}
}

